package io.renren.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.zxing.WriterException;
import io.renren.common.entity.*;
import io.renren.common.enums.*;
import io.renren.common.exception.ErrorCode;
import io.renren.common.exception.RenException;
import io.renren.common.service.impl.CrudServiceImpl;
import io.renren.common.validator.AssertUtils;
import io.renren.dao.*;
import io.renren.dto.LoginDTO;
import io.renren.dto.XlsUserDTO;
import io.renren.service.TokenService;
import io.renren.service.XlsLogCashService;
import io.renren.service.XlsUserService;
import io.renren.utils.AppResult;
import io.renren.utils.Md5Utils;
import io.renren.utils.QRCodeUtil.ZxingUtils;
import io.renren.utils.StringUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

/**
 * 用户
 *
 * @author Mark sunlightcs@gmail.com
 * @since 1.0.0 2020-03-28
 */
@Service
public class XlsUserServiceImpl extends CrudServiceImpl<XlsUserDao, XlsUserEntity, XlsUserDTO> implements XlsUserService {

    @Autowired
    private XlsUserDao xlsUserDao;
    @Autowired
    private XlsCirclePriDao xlsCirclePriDao;
    @Autowired
    private XlsUserCirclePriDao xlsUserCirclePriDao;
    @Autowired
    private XlsSecUserPriDao xlsSecUserPriDao;
    @Autowired
    private XlsThreeUserPriDao xlsThreeUserPriDao;
    @Autowired
    private XlsUserAwardDao xlsUserAwardDao;
    @Autowired
    private XlsLogCashDao xlsLogCashDao;

    @Autowired
    private XlsCircleHighDao xlsCircleHighDao;
    @Autowired
    private XlsUserCircleHighDao xlsUserCircleHighDao;
    @Autowired
    private XlsCircleSequenceHighDao xlsCircleSequenceHighDao;

    @Autowired
    private XlsUpgradeAccountDao xlsUpgradeAccountDao;

    @Autowired
    private TokenService tokenService;

    @Override
    public QueryWrapper<XlsUserEntity> getWrapper(Map<String, Object> params) {
        String id = (String) params.get("id");

        QueryWrapper<XlsUserEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(id), "id", id);

        return wrapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertUser(XlsUserEntity user) {
        //添加用户
        xlsUserDao.insert(user);
        //创建或更新圈子
        insertOrUpdateXlsCirclePri(user);
    }


/*********************************************** 高级start ************************************************/
    /**
     * 创建||更新县级圈子||创建用户县级圈子关系
     *
     * @param updateXlsUser
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertOrUpdateXlsCircleHigh(XlsUserEntity updateXlsUser) {
        //创建自己的高级圈子 添加用户圈子关系表-高级
        Integer circleLevel = updateXlsUser.getCircleLevel();
        int updateCircleLevel = getUpdateCircleLevel(circleLevel);
        updateXlsUser.setCircleLevel(updateCircleLevel);
        //更新用户等级
        xlsUserDao.updateById(updateXlsUser);
        insertXlsCircleHigh(updateXlsUser, updateCircleLevel);
    }

    /**
     * 创建高级圈子 添加用户圈子关系
     *
     * @param updateXlsUser
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertXlsCircleHigh(XlsUserEntity updateXlsUser, int circleLevel) {
        //通过高级圈子顺序表查询高级圈子是否存在
        QueryWrapper<XlsCircleSequenceHighEntity> xlsCircleHighEntityQueryWrapper = new QueryWrapper<>();
        xlsCircleHighEntityQueryWrapper.lambda()
                .eq(XlsCircleSequenceHighEntity::getCircleLevel, circleLevel)
                .eq(XlsCircleSequenceHighEntity::getIsDel, DeleteEnum.UNDELETED.value())
                .orderByAsc(XlsCircleSequenceHighEntity::getSequenceNum);
        List<XlsCircleSequenceHighEntity> xlsCircleSequenceHighEntityList = xlsCircleSequenceHighDao.selectList(xlsCircleHighEntityQueryWrapper);

        //创建高级圈子
        XlsCircleHighEntity xlsCircleHighEntity = XlsCircleHighEntity.builder()
                .topUserId(updateXlsUser.getId())
                .circleLevel(circleLevel)
                .build();
        xlsCircleHighDao.insert(xlsCircleHighEntity);
        //添加用户圈子关系
        insertUserCircleHigh(updateXlsUser, xlsCircleHighEntity);
        //创建高级圈子顺序表
        XlsCircleSequenceHighEntity xlsCircleSequenceHighEntity = XlsCircleSequenceHighEntity.builder()
                .circleId(xlsCircleHighEntity.getId())
                .circleLevel(circleLevel)
                .build();
        if (xlsCircleSequenceHighEntityList.size() > 0) {
            //设置高级圈子顺序表
            XlsCircleSequenceHighEntity pxlsCircleSequenceHighEntity = xlsCircleSequenceHighEntityList.get(0);
            xlsCircleSequenceHighEntity.setParentCircleId(pxlsCircleSequenceHighEntity.getCircleId());
            xlsCircleSequenceHighEntity.setSequenceNum(xlsCircleSequenceHighEntityList.get(xlsCircleSequenceHighEntityList.size() - 1).getSequenceNum() + 1);

            //处理 第一层
            //获取所属圈子
            XlsCircleHighEntity pXlsCircleHighEntity = xlsCircleHighDao.selectById(pxlsCircleSequenceHighEntity.getCircleId());
            //更新圈子
            pXlsCircleHighEntity.setCirclePeopleNum(pXlsCircleHighEntity.getCirclePeopleNum() + 1);
            xlsCircleHighDao.updateById(pXlsCircleHighEntity);
            //添加用户圈子关系表
            insertUserCircleHigh(updateXlsUser, pXlsCircleHighEntity);
            if (pXlsCircleHighEntity.getCirclePeopleNum() >= 3) {
                //添加奖励金额记录
                insertCashLog(null, pXlsCircleHighEntity, getLevelAward(circleLevel, pXlsCircleHighEntity.getCirclePeopleNum()));
                //给第一人奖励
                xlsUserAwardDao.updateAward(pXlsCircleHighEntity.getTopUserId(), getLevelAward(circleLevel, pXlsCircleHighEntity.getCirclePeopleNum()));
                //处理 第二层
                QueryWrapper<XlsCircleSequenceHighEntity> xlsCircleSequenceHighEntityQueryWrapper = new QueryWrapper<>();
                xlsCircleSequenceHighEntityQueryWrapper.lambda()
                        .eq(XlsCircleSequenceHighEntity::getParentCircleId, pXlsCircleHighEntity.getId())
                        .eq(XlsCircleSequenceHighEntity::getIsDel, DeleteEnum.UNDELETED.value());
                List<XlsCircleSequenceHighEntity> secondxlsCircleSequenceHighEntityList = xlsCircleSequenceHighDao.selectList(xlsCircleSequenceHighEntityQueryWrapper);
                if (pXlsCircleHighEntity.getCirclePeopleNum() > 3 && pXlsCircleHighEntity.getCirclePeopleNum() <= 5) {
                    //处理下级左侧
                    XlsCircleSequenceHighEntity xlsCircleSequenceHighEntityLeft = secondxlsCircleSequenceHighEntityList.get(0);
                    //获取所属圈子
                    XlsCircleHighEntity leftXlsCircleHighEntity = xlsCircleHighDao.selectById(xlsCircleSequenceHighEntityLeft.getCircleId());
                    //更新圈子
                    leftXlsCircleHighEntity.setCirclePeopleNum(leftXlsCircleHighEntity.getCirclePeopleNum() + 1);
                    xlsCircleHighDao.updateById(leftXlsCircleHighEntity);
                    //添加用户圈子关系表
                    insertUserCircleHigh(updateXlsUser, leftXlsCircleHighEntity);
                    //添加奖励金额记录
                    insertCashLog(null, leftXlsCircleHighEntity, getLevelAward(circleLevel, leftXlsCircleHighEntity.getCirclePeopleNum()));
                    //给第一人奖励
                    xlsUserAwardDao.updateAward(leftXlsCircleHighEntity.getTopUserId(), getLevelAward(circleLevel, leftXlsCircleHighEntity.getCirclePeopleNum()));

                    xlsCircleSequenceHighEntity.setParentCircleId(xlsCircleSequenceHighEntityLeft.getCircleId());
                } else if (pXlsCircleHighEntity.getCirclePeopleNum() >= 6 && pXlsCircleHighEntity.getCirclePeopleNum() <= 7) {
                    //处理下级右侧
                    XlsCircleSequenceHighEntity xlsCircleSequenceHighEntityRight = secondxlsCircleSequenceHighEntityList.get(1);
                    //获取所属圈子
                    XlsCircleHighEntity rightXlsCircleHighEntity = xlsCircleHighDao.selectById(xlsCircleSequenceHighEntityRight.getCircleId());
                    //更新圈子
                    rightXlsCircleHighEntity.setCirclePeopleNum(rightXlsCircleHighEntity.getCirclePeopleNum() + 1);
                    xlsCircleHighDao.updateById(rightXlsCircleHighEntity);
                    //添加用户圈子关系表
                    insertUserCircleHigh(updateXlsUser, rightXlsCircleHighEntity);
                    //添加奖励金额记录
                    insertCashLog(null, rightXlsCircleHighEntity, getLevelAward(circleLevel, rightXlsCircleHighEntity.getCirclePeopleNum()));
                    //给第一人奖励
                    xlsUserAwardDao.updateAward(rightXlsCircleHighEntity.getTopUserId(), getLevelAward(circleLevel, rightXlsCircleHighEntity.getCirclePeopleNum()));

                    xlsCircleSequenceHighEntity.setParentCircleId(xlsCircleSequenceHighEntityRight.getCircleId());
                }
            }
            if (pXlsCircleHighEntity.getCirclePeopleNum() == 7) {
                //todo 伞下100人处理逻辑待定
               /* //获取升级的用户
                XlsUserEntity updateXlsUserHigh = xlsCircleHighDao.getXlsUser(pXlsCircleHighEntity.getId());
                //升省级逻辑，即第7个人进来了并且伞下够100人
                if(updateXlsUser.getCircleLevel() == CircleLevelEnum.CITY_LEVEL.value()) {
                    //通过待升级的用户获取其所在的初级圈子
                    QueryWrapper<XlsCirclePriEntity> queryWrapper = new QueryWrapper<>();
                    queryWrapper.lambda().eq(XlsCirclePriEntity::getTopUserId, updateXlsUser.getId());
                    XlsCirclePriEntity xlsCirclePriEntity = xlsCirclePriDao.selectOne(queryWrapper);
                    //查看伞下是否够100人
                    int count = xlsCirclePriDao.selectCountByCircleId(xlsCirclePriEntity.getId());
                    if(count == 100) {
                        //所属高级圈子、高级圈子顺序表、用户圈子关系表设为删除状态
                        xlsCircleHighDao.deleteCircle(pXlsCircleHighEntity.getId());
                        //升级
                        insertOrUpdateXlsCircleHigh(updateXlsUserHigh);
                    }
                }else {
                    //所属高级圈子、高级圈子顺序表、用户圈子关系表设为删除状态
                    xlsCircleHighDao.deleteCircle(pXlsCircleHighEntity.getId());
                    //升级
                    insertOrUpdateXlsCircleHigh(updateXlsUserHigh);
                }*/
                //现有逻辑
                //所属高级圈子、高级圈子顺序表、用户圈子关系表设为删除状态
                xlsCircleHighDao.deleteCircle(pXlsCircleHighEntity.getId());
                //获取升级的用户
                XlsUserEntity updateXlsUserHigh = xlsCircleHighDao.getXlsUser(pXlsCircleHighEntity.getId());
                //升级
                insertOrUpdateXlsCircleHigh(updateXlsUserHigh);
            }
        }
        //初始创建
        xlsCircleSequenceHighDao.insert(xlsCircleSequenceHighEntity);
    }

    /**
     * 根据圈子等级、人数 获取奖励金额
     *
     * @param circleLevel
     * @param peopleNum
     * @return
     */
    public BigDecimal getLevelAward(int circleLevel, int peopleNum) {
        Integer[] countyArr = {0, 0, 1000, 500, 500, 500, 2500};
        Integer[] cityArr = {0, 0, 5000, 1000, 1000, 1000, 4500};
        Integer[] provinceArr = {0, 0, 25000, 10000, 10000, 10000, 45000};
        Integer[] partnerArr = {0, 0, 50000, 25000, 25000, 25000, 275000};
        BigDecimal award = new BigDecimal(0);
        int inx = peopleNum - 1;
        switch (circleLevel) {
            case 1:
                award = new BigDecimal(countyArr[inx]);
                break;
            case 2:
                award = new BigDecimal(cityArr[inx]);
                break;
            case 3:
                award = new BigDecimal(provinceArr[inx]);
                break;
            case 4:
                award = new BigDecimal(partnerArr[inx]);
                break;
        }
        return award;
    }

    /**
     * 添加用户圈子关系
     *
     * @param user
     * @param xlsCircleHighEntity
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertUserCircleHigh(XlsUserEntity user, XlsCircleHighEntity xlsCircleHighEntity) {
        XlsUserCircleHighEntity xlsUserCircleHighEntity = XlsUserCircleHighEntity.builder()
                .circleId(xlsCircleHighEntity.getId())
                .xlsUserId(user.getId())
                .build();
        xlsUserCircleHighDao.insert(xlsUserCircleHighEntity);
    }

    /**
     * 获取待升级的等级
     *
     * @param circleLevel
     * @return
     */
    public int getUpdateCircleLevel(int circleLevel) {
        int result = 0;
        switch (circleLevel) {
            case 0:
                result = CircleLevelEnum.COUNTY_LEVEL.value();
                break;
            case 1:
                result = CircleLevelEnum.CITY_LEVEL.value();
                break;
            case 2:
                result = CircleLevelEnum.PROVINCE_LEVEL.value();
                break;
            case 3:
                result = CircleLevelEnum.PARTNER_LEVEL.value();
                break;
        }

        return result;
    }


/*********************************************** 高级end ************************************************/


/*********************************************** 初级start ************************************************/
    /**
     * 创建||更新初级圈子||创建用户初级圈子关系
     *
     * @param user
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void insertOrUpdateXlsCirclePri(XlsUserEntity user) {
        //添加初级圈子 （判断用户是否有邀请人 为空 第一人创建初级圈子 添加用户圈子关系表-初级）
        if (StrUtil.isEmpty(user.getInviterId())) {
            insertXlsCirclePri(user, UserLevelEnum.ROOT_LEVEL.value());
        }
        //加入邀请人所属圈子
        else {
            //通过邀请人判断 用户圈子关系 是否存在
            QueryWrapper<XlsUserCirclePriEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(XlsUserCirclePriEntity::getXlsUserId, user.getInviterId())
                    .eq(XlsUserCirclePriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                    .orderByAsc(XlsUserCirclePriEntity::getXlsUserLevel);
            List<XlsUserCirclePriEntity> xlsUserCirclePriEntityList = xlsUserCirclePriDao.selectList(queryWrapper);
            //说明用户已升级
            if (xlsUserCirclePriEntityList.size() == 0) {
                //查询树的最低端
                //TODO
            } else {
                switch (xlsUserCirclePriEntityList.size()) {
                    case 1:
                        //圈子中顶级用户邀请
                        handlerUserCircle(user, xlsUserCirclePriEntityList.get(0).getCircleId());
                        break;
                    case 2:
                        for (int i = 0; i < 2; i++) {
                            //第二层
                            if (i == 0) {
                                /*
                                 * 首先查看上级圈子中的人数是否大于3人
                                 * 小于3人，continue 跳出循环
                                 * 否则 先查看上级圈子中的左侧二级用户的下级二级用户是否达到2人
                                 *      未达到 加入左侧二级用户所属圈子  如达到 加入右侧二级用户所属圈子
                                 */
                                Long parentCircleId = xlsUserCirclePriEntityList.get(1).getCircleId();
                                XlsCirclePriEntity parentCirclePriEntity = xlsCirclePriDao.selectOne(new QueryWrapper<XlsCirclePriEntity>().lambda().eq(XlsCirclePriEntity::getId, parentCircleId));
                                if (3 > parentCirclePriEntity.getCirclePeopleNum()) {
                                    continue;
                                } else {
                                    //上级圈子中的左侧二级用户
                                    XlsSecUserPriEntity xlsLeftSecUserPriEntity = xlsSecUserPriDao.selectOne(new QueryWrapper<XlsSecUserPriEntity>().lambda()
                                            .eq(XlsSecUserPriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                                            .eq(XlsSecUserPriEntity::getIsLeft, LeftEnum.LEFT.value())
                                            .eq(XlsSecUserPriEntity::getCircleId, parentCircleId)
                                    );
                                    //左侧下级圈子
                                    XlsCirclePriEntity xlsLeftCirclePriEntity = xlsCirclePriDao.selectOne(new QueryWrapper<XlsCirclePriEntity>().lambda()
                                            .eq(XlsCirclePriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                                            .eq(XlsCirclePriEntity::getTopUserId, xlsLeftSecUserPriEntity.getXlsUserId())
                                    );
                                    //下级圈子二级用户数
                                    Integer count = xlsSecUserPriDao.selectCount(new QueryWrapper<XlsSecUserPriEntity>().lambda()
                                            .eq(XlsSecUserPriEntity::getCircleId, xlsLeftCirclePriEntity.getId())
                                            .eq(XlsSecUserPriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                                    );
                                    //未达到 加入下级圈子
                                    if (2 > count) {
                                        handlerUserCircle(user, xlsLeftCirclePriEntity.getId());
                                    } else {
                                        //达到 加入右侧二级用户所属圈子
                                        XlsSecUserPriEntity xlsRightSecUserPriEntity = xlsSecUserPriDao.selectOne(new QueryWrapper<XlsSecUserPriEntity>().lambda()
                                                .eq(XlsSecUserPriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                                                .eq(XlsSecUserPriEntity::getIsLeft, LeftEnum.RIGHT.value())
                                                .eq(XlsSecUserPriEntity::getCircleId, parentCircleId)
                                        );
                                        //右侧下级圈子
                                        XlsCirclePriEntity xlsRightCirclePriEntity = xlsCirclePriDao.selectOne(new QueryWrapper<XlsCirclePriEntity>().lambda()
                                                .eq(XlsCirclePriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                                                .eq(XlsCirclePriEntity::getTopUserId, xlsRightSecUserPriEntity.getXlsUserId())
                                        );
                                        handlerUserCircle(user, xlsRightCirclePriEntity.getId());
                                    }
                                }
                            } else if (i == 1) {//第一层
                                handlerUserCircle(user, xlsUserCirclePriEntityList.get(1).getCircleId());
                            }
                        }
                        break;
                    case 3:
                        //圈子中三级用户邀请
                        for (int i = 0; i < 3; i++) {
                            if (i == 0) {
                                continue;
                            } else {
                                //第二层
                                if (i == 1) {
                                    /*
                                     * 首先查看上级圈子中的人数是否大于3人
                                     * 小于3人，continue 跳出循环
                                     * 否则 先查看上级圈子中的左侧二级用户的下级二级用户是否达到2人
                                     *      未达到 加入左侧二级用户所属圈子  如达到 加入右侧二级用户所属圈子
                                     */
                                    Long parentCircleId = xlsUserCirclePriEntityList.get(2).getCircleId();
                                    XlsCirclePriEntity parentCirclePriEntity = xlsCirclePriDao.selectOne(new QueryWrapper<XlsCirclePriEntity>().lambda().eq(XlsCirclePriEntity::getId, parentCircleId));
                                    //上级圈子中的左侧二级用户
                                    XlsSecUserPriEntity xlsLeftSecUserPriEntity = xlsSecUserPriDao.selectOne(new QueryWrapper<XlsSecUserPriEntity>().lambda()
                                            .eq(XlsSecUserPriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                                            .eq(XlsSecUserPriEntity::getIsLeft, LeftEnum.LEFT.value())
                                            .eq(XlsSecUserPriEntity::getCircleId, parentCircleId)
                                    );
                                    //左侧下级圈子
                                    XlsCirclePriEntity xlsLeftCirclePriEntity = xlsCirclePriDao.selectOne(new QueryWrapper<XlsCirclePriEntity>().lambda()
                                            .eq(XlsCirclePriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                                            .eq(XlsCirclePriEntity::getTopUserId, xlsLeftSecUserPriEntity.getXlsUserId())
                                    );
                                    //下级圈子二级用户数
                                    Integer count = xlsSecUserPriDao.selectCount(new QueryWrapper<XlsSecUserPriEntity>().lambda()
                                            .eq(XlsSecUserPriEntity::getCircleId, xlsLeftCirclePriEntity.getId())
                                            .eq(XlsSecUserPriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                                    );
                                    //未达到 加入下级圈子
                                    if (2 > count) {
                                        handlerUserCircle(user, xlsLeftCirclePriEntity.getId());
                                    } else {
                                        //达到 加入右侧二级用户所属圈子
                                        XlsSecUserPriEntity xlsRightSecUserPriEntity = xlsSecUserPriDao.selectOne(new QueryWrapper<XlsSecUserPriEntity>().lambda()
                                                .eq(XlsSecUserPriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                                                .eq(XlsSecUserPriEntity::getIsLeft, LeftEnum.RIGHT.value())
                                                .eq(XlsSecUserPriEntity::getCircleId, parentCircleId)
                                        );
                                        //右侧下级圈子
                                        XlsCirclePriEntity xlsRightCirclePriEntity = xlsCirclePriDao.selectOne(new QueryWrapper<XlsCirclePriEntity>().lambda()
                                                .eq(XlsCirclePriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                                                .eq(XlsCirclePriEntity::getTopUserId, xlsRightSecUserPriEntity.getXlsUserId())
                                        );
                                        handlerUserCircle(user, xlsRightCirclePriEntity.getId());
                                    }
                                } else if (i == 2) {//第一层
                                    handlerUserCircle(user, xlsUserCirclePriEntityList.get(2).getCircleId());
                                }
                            }
                        }
                        break;
                }
            }
            //创建自己的初级圈子 添加用户圈子关系表-初级
            insertXlsCirclePri(user, UserLevelEnum.ROOT_LEVEL.value());
        }
    }


    /**
     * 处理二级用户、三级用户 更新圈子、添加用户圈子关系
     *
     * @param user
     * @param circleId
     */
    @Transactional(rollbackFor = Exception.class)
    public void handlerUserCircle(XlsUserEntity user, Long circleId) {
        //获取所属圈子
        XlsCirclePriEntity xlsCirclePriEntity = xlsCirclePriDao.selectById(circleId);

        //通过圈子id查询二级用户 不存在则添加
        QueryWrapper<XlsSecUserPriEntity> secQueryWrapper = new QueryWrapper<>();
        secQueryWrapper.lambda()
                .eq(XlsSecUserPriEntity::getCircleId, xlsCirclePriEntity.getId())
                .eq(XlsSecUserPriEntity::getIsDel, DeleteEnum.UNDELETED.value());
        List<XlsSecUserPriEntity> xlsSecUserPriEntityList = xlsSecUserPriDao.selectList(secQueryWrapper);
        //二级用户已存在
        if (xlsSecUserPriEntityList.size() > 0) {
            if (xlsSecUserPriEntityList.size() == 1) {
                //创建二级用户、更新圈子、添加二级用户圈子关系 (放右侧)
                insertSecUserPri(user, xlsCirclePriEntity, false);
                //添加奖励金额记录
                insertCashLog(xlsCirclePriEntity, null, new BigDecimal(500));
                //给顶级用户500元奖励
                XlsUserAwardEntity xlsUserAwardEntity = XlsUserAwardEntity.builder()
                        .xlsUserId(xlsCirclePriEntity.getTopUserId())
                        .awardPrice(new BigDecimal(500))
                        .build();
                xlsUserAwardDao.insert(xlsUserAwardEntity);

            } else { //查询三级用户
                //通过圈子id查询三级用户 不存在则添加
                QueryWrapper<XlsThreeUserPriEntity> threeQueryWrapper = new QueryWrapper<>();
                threeQueryWrapper.lambda()
                        .eq(XlsThreeUserPriEntity::getCircleId, xlsCirclePriEntity.getId())
                        .eq(XlsThreeUserPriEntity::getIsDel, DeleteEnum.UNDELETED.value());
                List<XlsThreeUserPriEntity> xlsThreeUserPriEntityList = xlsThreeUserPriDao.selectList(threeQueryWrapper);

                int xlsThreeUserPriEntityListSize = xlsThreeUserPriEntityList.size();
                //三级用户已存在
                if (xlsThreeUserPriEntityListSize > 0) {
                    if (xlsThreeUserPriEntityListSize == 1) {
                        //创建三级用户、更新圈子、添加用户圈子关系 (放左侧)
                        insertThreeUserPri(user, xlsCirclePriEntity, true);
                    } else {
                        //创建三级用户、更新圈子、添加用户圈子关系 (放右侧)
                        insertThreeUserPri(user, xlsCirclePriEntity, false);
                        /*达到7人 顶级用户升级为县级 所属初级圈子、二级用户、三级用户设为删除状态 调用高级圈子逻辑*/
                        if ((xlsThreeUserPriEntityListSize + 1) == 4) {
                            //添加奖励金额记录
                            insertCashLog(xlsCirclePriEntity, null, new BigDecimal(2500));
                            //给顶级用户2500元奖励
                            xlsUserAwardDao.updateAward(xlsCirclePriEntity.getTopUserId(), new BigDecimal(2500));
                            //所属初级圈子、二级用户、三级用户设为删除状态
                            xlsCirclePriDao.deleteCircle(xlsCirclePriEntity.getId());
                            //调用高级圈子逻辑
                            //获取升级的用户
                            XlsUserEntity updateXlsUser = xlsCirclePriDao.getXlsUser(xlsCirclePriEntity.getId());
                            //升级
                            insertOrUpdateXlsCircleHigh(updateXlsUser);
                        }
                    }
                } else {//三级用户不存在则创建
                    //创建三级用户、更新圈子、添加用户圈子关系 (放左侧)
                    insertThreeUserPri(user, xlsCirclePriEntity, true);
                }
            }
        } else {//二级用户不存在则创建
            //创建二级用户、更新圈子、添加二级用户圈子关系 (放左侧)
            insertSecUserPri(user, xlsCirclePriEntity, true);
        }
    }

    /**
     * 添加奖励金额记录
     *
     * @param xlsCirclePriEntity
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertCashLog(XlsCirclePriEntity xlsCirclePriEntity, XlsCircleHighEntity pXlsCircleHighEntity, BigDecimal cash) {
        Long topUserId = null != xlsCirclePriEntity ? xlsCirclePriEntity.getTopUserId() : pXlsCircleHighEntity.getTopUserId();
        //获取奖励前余额
        XlsUserAwardEntity userAwardEntity = xlsUserAwardDao.selectUserAwardByUserId(topUserId);
        BigDecimal preCash = new BigDecimal(0);
        if (ObjectUtil.isNotEmpty(userAwardEntity)) {
            preCash = userAwardEntity.getAwardPrice();
        }
        //添加奖励金额记录
        xlsLogCashDao.insert(XlsLogCashEntity.builder()
                .cashType(1)
                .createTime(new Date())
                .dataFlag(1)
                .fromId(1L)
                .userId(topUserId)
                .cash(cash)
                .orderNo("")
                .preCash(preCash)
                .remark("平台奖励")
                .type(CashtypeEnum.REWARDS_ACCOUNT.value())
                .build());
    }


    /**
     * 创建初级圈子 添加用户圈子关系
     *
     * @param user
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertXlsCirclePri(XlsUserEntity user, int userLevel) {

        //创建初级圈子
        XlsCirclePriEntity xlsCirclePriEntity = XlsCirclePriEntity.builder()
                .topUserId(user.getId())
                .build();
        xlsCirclePriDao.insert(xlsCirclePriEntity);
        //添加用户圈子关系
        insertUserCircle(user, xlsCirclePriEntity, userLevel);
    }

    /**
     * 创建三级用户、更新圈子、添加用户圈子关系
     *
     * @param user
     * @param xlsCirclePriEntity
     * @param isLeft             是否左侧
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertThreeUserPri(XlsUserEntity user, XlsCirclePriEntity xlsCirclePriEntity, boolean isLeft) {
        //查询二级用户
        QueryWrapper<XlsSecUserPriEntity> secQueryWrapper = new QueryWrapper<>();
        secQueryWrapper.lambda()
                .eq(XlsSecUserPriEntity::getCircleId, xlsCirclePriEntity.getId())
                .eq(XlsSecUserPriEntity::getIsDel, DeleteEnum.UNDELETED.value())
                .eq(XlsSecUserPriEntity::getIsLeft, isLeft ? LeftEnum.LEFT.value() : LeftEnum.RIGHT.value());
        XlsSecUserPriEntity xlsSecUserPriEntity = xlsSecUserPriDao.selectOne(secQueryWrapper);
        //创建三级用户
        XlsThreeUserPriEntity xlsThreeUserPriEntity = XlsThreeUserPriEntity.builder()
                .circleId(xlsCirclePriEntity.getId())
                .parentId(xlsSecUserPriEntity.getXlsUserId())
                .isLeft(isLeft ? LeftEnum.LEFT.value() : LeftEnum.RIGHT.value())
                .xlsUserId(user.getId())
                .build();
        xlsThreeUserPriDao.insert(xlsThreeUserPriEntity);
        //更新圈子
        xlsCirclePriEntity.setCirclePeopleNum(xlsCirclePriEntity.getCirclePeopleNum() + 1);
        xlsCirclePriDao.updateById(xlsCirclePriEntity);
        //添加用户圈子关系
        insertUserCircle(user, xlsCirclePriEntity, UserLevelEnum.THREE_LEVEL.value());
    }

    /**
     * 创建二级用户、更新圈子、添加用户圈子关系
     *
     * @param user
     * @param xlsCirclePriEntity
     * @param isLeft             是否左侧
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertSecUserPri(XlsUserEntity user, XlsCirclePriEntity xlsCirclePriEntity, boolean isLeft) {
        //创建二级用户
        XlsSecUserPriEntity xlsSecUserPriEntity = XlsSecUserPriEntity.builder()
                .circleId(xlsCirclePriEntity.getId())
                .parentId(xlsCirclePriEntity.getTopUserId())
                .isLeft(isLeft ? LeftEnum.LEFT.value() : LeftEnum.RIGHT.value())
                .xlsUserId(user.getId())
                .build();
        xlsSecUserPriDao.insert(xlsSecUserPriEntity);
        //更新圈子
        xlsCirclePriEntity.setCirclePeopleNum(xlsCirclePriEntity.getCirclePeopleNum() + 1);
        xlsCirclePriDao.updateById(xlsCirclePriEntity);
        //添加用户圈子关系
        insertUserCircle(user, xlsCirclePriEntity, UserLevelEnum.SECOND_LEVEL.value());
    }

    /**
     * 添加用户圈子关系
     *
     * @param user
     * @param xlsCirclePriEntity
     */
    @Transactional(rollbackFor = Exception.class)
    public void insertUserCircle(XlsUserEntity user, XlsCirclePriEntity xlsCirclePriEntity, int userLevel) {
        XlsUserCirclePriEntity xlsUserCirclePriEntity = XlsUserCirclePriEntity.builder()
                .circleId(xlsCirclePriEntity.getId())
                .xlsUserLevel(userLevel == UserLevelEnum.ROOT_LEVEL.value() ? UserLevelEnum.ROOT_LEVEL.value()
                        : userLevel == UserLevelEnum.SECOND_LEVEL.value() ? UserLevelEnum.SECOND_LEVEL.value()
                        : UserLevelEnum.THREE_LEVEL.value())
                .xlsUserId(user.getId())
                .build();
        xlsUserCirclePriDao.insert(xlsUserCirclePriEntity);
    }

    /*********************************************** 初级end ************************************************/

    @Override
    public XlsUserEntity getByMobile(String mobile) {
        return baseDao.getUserByMobile(mobile);
    }

    @Override
    public XlsUserEntity getUserByUsername(String username) {
        return baseDao.getUserByUsername(username);
    }

    @Override
    public XlsUserEntity getUserByUserId(Long userId) {
        return baseDao.getUserByUserId(userId);
    }

    @Override
    public Map<String, Object> login(LoginDTO dto) {
        XlsUserEntity user = getByMobile(dto.getMobile());
        AssertUtils.isNull(user, ErrorCode.ACCOUNT_PASSWORD_ERROR);

        //密码错误
        if (!user.getPassword().equals(DigestUtils.sha256Hex(dto.getPassword()))) {
            throw new RenException(ErrorCode.ACCOUNT_PASSWORD_ERROR);
        }

        //获取登录token
        TokenEntity tokenEntity = tokenService.createToken(user.getId());

        Map<String, Object> map = new HashMap<>(2);
        map.put("userId", user.getId());
        map.put("token", tokenEntity.getToken());
        map.put("expire", tokenEntity.getExpireDate().getTime() - System.currentTimeMillis());

        return map;
    }


    /**
     * 注册用户并返回Id
     *
     * @param user
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void registerUsers(XlsUserEntity user) {
        xlsUserDao.insert(user);
        XlsUserEntity xlsUserEntity = xlsUserDao.selectUserByUserPhone(user.getMobile());

        XlsUpgradeAccountEntity upgradeAccount = XlsUpgradeAccountEntity.builder()
                .accCash(BigDecimal.ZERO)
                .totalCash(BigDecimal.ZERO)
                .userId(xlsUserEntity.getId())
                .build();
        xlsUpgradeAccountDao.insert(upgradeAccount);
    }


    /**
     * 个人中心
     *
     * @param userId
     * @return
     */
    @Override
    public AppResult myCenterData(Long userId) {
        Map<String, Object> map = new HashMap<>();
        if (userId == null || userId.equals(null)) {
            return AppResult.ERROR("获取数据失败");
        } else {
            XlsUserEntity users = xlsUserDao.selectById(userId);
            XlsUserAwardEntity account = xlsUserAwardDao.selectUserAwardByUserId(userId);
            map.put("users", users);
            if (io.renren.utils.StringUtils.isNull(account)) {
                XlsUserAwardEntity xlsUserAwardEntity = new XlsUserAwardEntity();
                xlsUserAwardEntity.setAwardPrice(new BigDecimal(0));
                map.put("account", xlsUserAwardEntity);
            } else {
                map.put("account", account);
            }
            return AppResult.OK(map);
        }
    }

    @Override
    public Map<String, Object> checkPayPassWorld(Long userId, String paypassword) {
        Map<String, Object> resultMap = new HashMap();

        XlsUserEntity user = xlsUserDao.selectById(userId);
        if (StringUtils.isNull(user)) {
            resultMap.put("status", "-1");
            resultMap.put("msg", "无效用户，请重新登录");
            return resultMap;
        }
        String pPwd = Md5Utils.hash(paypassword + user.getSalt());
        String payPassword = user.getPayPassword();
        if (StringUtils.isEmpty(payPassword)) {
            resultMap.put("status", "-1");
            resultMap.put("msg", "请设置支付密码");
            return resultMap;
        }
        if (StringUtils.isEmpty(paypassword)) {
            resultMap.put("status", "-1");
            resultMap.put("msg", "请输入支付密码");
            return resultMap;
        }
        if (pPwd.equals(payPassword)) {
            resultMap.put("status", "1");
            // json.put("msg","下单成功");
        } else {
            resultMap.put("status", "-1");
            resultMap.put("msg", "支付密码错误，请重新输入");
        }
        return resultMap;
    }

    @Override
    public AppResult qrCodeShare(Long userId) {
        Map<String, Object> map = new HashMap<>();
		/*QrcodeAround qrcodeAround=qrcodeAroundService.selectQrcodeAroundByuserId(userId);
		model.addAttribute("qrcodeAround",qrcodeAround);         */                            //二维码四周的文字
        //String backgroundPath = "http://lianmengshangqi.oss-cn-beijing.aliyuncs.com/imgs/20/1544877696811.png";    //二维码背景图
        XlsUserEntity users = xlsUserDao.selectById(userId);
        String userPhone = users.getMobile();
        //二维码宽度
        int width = 493;
        //二维码高度
        int height = 493;
        //二维码内容
        /*String contcent ="http://192.168.3.152:8000/shopdemo/tmp/detail/register.html?userPhone="+userPhone;*/
        String contcent = "http://zhonghe.56365.cc:8011/api/tmp/detail/register.html?userPhone=" + userPhone;
        BufferedImage zxingImage = null;
        try {
            //二维码图片流
            zxingImage = ZxingUtils.enQRCode(contcent, width, height);
        } catch (WriterException e) {
            e.printStackTrace();
        }
        String qrCode = "";
        try {
            //合成二维码和背景图
            //BufferedImage image = ZxingUtils.drawImage(backgroundPath, zxingImage, 224, 754);
            //图片转inputStream
            InputStream inputStream = ZxingUtils.bufferedImageToInputStream(zxingImage);
            byte[] data = new byte[inputStream.available()];
            inputStream.read(data);
            inputStream.close();
            qrCode = new String(Base64.encodeBase64(data));
        } catch (IOException e) {
            e.printStackTrace();
        }

        map.put("userPhone", userPhone);
        map.put("qrCode", qrCode);
        return AppResult.OK("获取成功", map);
    }

    @Override
    public AppResult fans(Long userId) {
        int teamNum = 0;
        List<XlsUserEntity> list = xlsUserDao.fans(userId);     //我推荐的人
        List<Map<String, Object>> userList = new ArrayList<>();
        Map<String, Object> mapes = new HashMap<>();
        if (list.size() > 0) {
            for (XlsUserEntity users : list) {
                Map<String, Object> maps = new HashMap<>();
                maps.put("userName", users.getUsername());
                maps.put("userPhone", users.getMobile());
//                Long userId1 = users.getId();
                /*totalCash+=new BigDecimal(maps.get("teamCash").toString()).doubleValue();*/
                userList.add(maps);
            }
        }
        mapes.put("usersList", userList);
        mapes.put("totalTeam", teamNum);
        return AppResult.OK("获取成功", mapes);
    }

    @Override
    public AppResult promotePeople(Long userId) {
        XlsUserEntity xlsUserEntity = xlsUserDao.selectById(userId);
        if (StringUtils.isNotNull(xlsUserEntity)) {
            XlsUserEntity xlsUserEntity1 = xlsUserDao.selectById(xlsUserEntity.getInviterId());
            Map<String, Object> map = new HashMap<>();
            map.put("users", xlsUserEntity1);
            return AppResult.OK(map);
        }
        return AppResult.ERROR("你没有推荐人");
    }

    @Override
    @Transactional
    public AppResult updatePassword(Long userid, String oldPassword, String newPassword, String types, String userPhone) {
        XlsUserEntity users = xlsUserDao.selectById(userid);
        /*String  pas= Md5Utils.hash(users.getPassword()+users.getSalt());*/
        if (StringUtils.isEmpty(oldPassword)) {
            return AppResult.ERROR("原密码不能为空");
        }
        if (StringUtils.isEmpty(newPassword)) {
            return AppResult.ERROR("新密码不能为空");
        }
        if (oldPassword.equals(newPassword)) {
            return AppResult.ERROR("原密码与新密码一样");
        }
        if (StringUtils.isNotNull(userPhone)) {
            users = xlsUserDao.selectUserByUserPhone(userPhone);
        }
        String oldpas = DigestUtils.sha256Hex(oldPassword);
        if (oldpas.equals(users.getPassword())) {
            String newPass = DigestUtils.sha256Hex(newPassword);
            users.setPassword(newPass);
            int i = xlsUserDao.updateById(users);
            if (i < 1) {
                return AppResult.ERROR("修改失败");
            }
        }
        return AppResult.OK("修改成功");
    }

    @Override
    @Transactional
    public AppResult updatePayPassword(Long userid, String oldPayPassword, String newPayPassword) {
        XlsUserEntity users = xlsUserDao.selectById(userid);
        if (StringUtils.isEmpty(oldPayPassword)) {
            return AppResult.ERROR("原二级密码不能为空");
        }
        if (StringUtils.isEmpty(newPayPassword)) {
            return AppResult.ERROR("新二级密码不能为空");
        }
        if (oldPayPassword.equals(newPayPassword)) {
            return AppResult.ERROR("原密码与新密码一样");
        }
        String oldPay = Md5Utils.hash(oldPayPassword + users.getSalt());
        if (users.getPayPassword().equals(oldPay)) {
            String newPay = Md5Utils.hash(newPayPassword + users.getSalt());
            users.setPayPassword(newPay);
            xlsUserDao.updateById(users);
            return AppResult.OK("修改成功");
        } else {
            return AppResult.ERROR("原二级密码不一致");
        }
    }

    @Override
    @Transactional
    public AppResult setPayPassword(Long userid, String newPayPassword) {
        XlsUserEntity users = xlsUserDao.selectById(userid);
        String newpays = "";
        if (StringUtils.isEmpty(newPayPassword)) {
            return AppResult.ERROR("新密码不能为空");
        }
        if (StringUtils.isNull(users.getSalt()) || users.getSalt().equals(0)) {
            Random random = new Random();
            int salt = random.nextInt(9000) + 1000;
            users.setSalt(salt);
        }
        newpays = Md5Utils.hash(newPayPassword + users.getSalt());
        users.setPayPassword(newpays);
        xlsUserDao.updateById(users);
        return AppResult.OK("设置成功");
    }


}